﻿using HiSport.Application.HiSportService.Bas.BasDtos;
using HiSport.Application.HiSportService.Bas.BasSportsEventsTypeManagement.Dtos;
using HiSport.Core.Entity.HiSportEntity.Bas;


namespace HiSport.Application.HiSportService.Bas.BasSportsEventsTypeManagement.Service
{
    /// <summary>
    /// 运动项目类型
    /// </summary>
    //[ApiDescriptionSettings("基础资料", Tag = "运动项目类型", SplitCamelCase = false)]
    [ApiDescriptionSettings("VenueSetup", Tag = "SportsType", SplitCamelCase = false)]
    public class SportsTypeService : ITransient, ISportsTypeService, IDynamicApiController
    {

        private readonly SqlSugarRepository<BasSportsEventsType> _sportEventsTypeRep;
        private readonly SqlSugarRepository<BasVenuesEventsType> _basVenuesEventsTypeRep;
        private readonly SqlSugarRepository<BasSiteType> _basSiteTypeRep;

        public SportsTypeService(SqlSugarRepository<BasSportsEventsType> sportEventsTypeRep,
            SqlSugarRepository<BasVenuesEventsType> basVenuesEventsTypeRep,
            SqlSugarRepository<BasSiteType> basSiteTypeRep)
        {
            _sportEventsTypeRep = sportEventsTypeRep;
            _basVenuesEventsTypeRep = basVenuesEventsTypeRep;
            _basSiteTypeRep = basSiteTypeRep;
        }

        /// <summary>
        /// 运动项目类型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>       
        [ApiDescriptionSettings(Name = "Create"), HttpPost]
        [DisplayName("创建项目类型")]
        public async Task<long> Create(SportsTypeCreateUpdateDto input)
        {
            #region 验证参数

            await CheckParam(input, true);

            #endregion

            #region 业务逻辑验证

            //名称和值不能重复
            var isAnyName = await _sportEventsTypeRep.IsAnyAsync(a => a.IsDelete == false && a.SportsEventsName == input.SportsEventsName);
            if (isAnyName)
            {
                throw Oops.Oh($"{input.SportsEventsName}-名称已存在");
            }
            var isAnyCode = await _sportEventsTypeRep.IsAnyAsync(a => a.IsDelete == false && a.SportsEventsCode == input.SportsEventsCode);
            if (isAnyCode)
            {
                throw Oops.Oh($"{input.SportsEventsCode}-值已存在");
            }
            #endregion

            #region 保存           
            input.Id = 0;//创建的时候ID必须=0
            var newOrg = await _sportEventsTypeRep.AsInsertable(input.Adapt<BasSportsEventsType>()).ExecuteReturnEntityAsync();
            return newOrg.Id;
            #endregion
        }


        /// <summary>
        /// 修改运动项目类型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>       
        [ApiDescriptionSettings(Name = "Update")]
        [DisplayName("修改运动项目类型")]
        public async Task Update(SportsTypeCreateUpdateDto input)
        {
            #region 验证参数

            await CheckParam(input, false);

            #endregion

            #region 修改           

            await _sportEventsTypeRep.AsUpdateable(input.Adapt<BasSportsEventsType>()).IgnoreColumns(true).ExecuteCommandAsync();

            #endregion

        }


        /// <summary>
        /// 查询单个运动项目类型
        /// </summary>
        /// <param name="id">场地类型ID</param>
        /// <returns></returns>       
        [ApiDescriptionSettings(Name = "Get"), HttpGet]
        [DisplayName("查询单个运动项目类型")]
        public async Task<SportsTypeBasicDto> Get(long id)
        {
            var data = await GetSportsType(id);
            var result = data.Adapt<SportsTypeBasicDto>();
            return result;

        }

        /// <summary>
        /// 查询运动项目类型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>       
        [ApiDescriptionSettings(Name = "GetListPage"), HttpPost]
        [DisplayName("查询运动项目类型列表")]
        public async Task<SqlSugarPagedList<SportsTypeBasicDto>> GetListPage(SportsTypeInputDto input)
        {
            ParamNull(input);
            var data = SqlWhere(input);
            if (data == null) return new SqlSugarPagedList<SportsTypeBasicDto>();

            //排序 分页
            var result = await data.OrderBuilder(input)
                .Select(x => new SportsTypeBasicDto()
                {
                    Id = x.Id.SelectAll(),
                })
                .ToPagedListAsync(input.Page, input.PageSize);

            return result;
        }

        /// <summary>
        /// 删除运动类型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [UnitOfWork]
        [ApiDescriptionSettings(Name = "Delete"), HttpPost]
        [DisplayName("删除运动类型")]
        public async Task Delete(DeleteInputDto input)
        {
            ParamNull(input);

            var id = input.Id;
            var data = await GetSportsType(id);
            var code = data.SportsEventsCode;

            //运动类型
            var isAny = _basVenuesEventsTypeRep.IsAny(a => a.SportsEventsTypeCode == code && a.IsDelete == false);
            if (isAny) throw Oops.Oh("已经引用不能删除");
            isAny = _basSiteTypeRep.IsAny(a => a.SportsEventsTypeCode == code && a.IsDelete == false);
            if (isAny) throw Oops.Oh("已经引用不能删除");

            //await _sportEventsTypeRep.FakeDeleteAsync(data);
            data.IsDelete = false;
            await _sportEventsTypeRep.UpdateAsync(data);
        }


        #region 私有方法

        /// <summary>
        /// 参数为NULL验证
        /// </summary>
        /// <param name="input"></param>
        private void ParamNull(object input)
        {
            if (input == null) throw Oops.Oh("参数错误:参数为NULL");
        }

        /// <summary>
        /// 查询场地类型
        /// </summary>
        private async Task<BasSportsEventsType> GetSportsType(long id)
        {
            var data = await _sportEventsTypeRep.GetFirstAsync(a => a.IsDelete == false && a.Id == id);
            if (data == null)
            {
                throw Oops.Oh("未查询到当前运动项目类型");
            }
            return data;
        }


        /// <summary>
        /// 运动项目类型查询条件
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<BasSportsEventsType> SqlWhere(SportsTypeInputDto input)
        {
            ParamNull(input);
            var data = _sportEventsTypeRep.AsQueryable();
            data = data.Where(a => a.IsDelete == false);

            #region 类型名称
            var name = input.SportsEventsName;
            if (!string.IsNullOrWhiteSpace(name))
            {
                data = data.Where(a => a.SportsEventsName.Contains(name));
            }
            #endregion

            #region code
            var sportsEventsCode = input.SportsEventsCode;
            if (!string.IsNullOrWhiteSpace(sportsEventsCode))
            {
                data = data.Where(a => a.SportsEventsCode.Contains(sportsEventsCode));
            }
            #endregion

            #region 停用、启用
            var status = input.Status;
            if (status != null && status.HasValue && status.Value > 0)
            {
                data = data.Where(a => a.Status == status);
            }

            #endregion 

            return data;
        }

        /// <summary>
        /// 验证参数
        /// </summary>
        /// <param name="input"></param>
        /// <param name="isCreate"></param>
        /// <returns></returns>
        private async Task CheckParam(SportsTypeCreateUpdateDto input, bool isCreate)
        {
            #region 验证参数

            ParamNull(input);

            var name = input.SportsEventsName;
            if (string.IsNullOrWhiteSpace(name))
            {
                throw Oops.Oh("参数错误:名称不能为空");
            }
            var code = input.SportsEventsCode;
            if (string.IsNullOrWhiteSpace(code))
            {
                throw Oops.Oh("参数错误:值(编码)不能为空");
            }

            var status = input.Status;
            var stausList = new List<short> { 1, 2 };
            if (!stausList.Contains(status))
            {
                throw Oops.Oh("参数错误:状态有误");
            }


            //场馆编码：租户内唯一，必填，
            //场馆名称：租户内唯一，必填
            var isSame = false;
            if (isCreate)
            {
                //名称和值不能重复
                var isAnyName = await _sportEventsTypeRep.IsAnyAsync(a => a.IsDelete == false && a.SportsEventsName == input.SportsEventsName);
                if (isAnyName)
                {
                    throw Oops.Oh($"{input.SportsEventsName}-名称已存在");
                }
                var isAnyCode = await _sportEventsTypeRep.IsAnyAsync(a => a.IsDelete == false && a.SportsEventsCode == input.SportsEventsCode);
                if (isAnyCode)
                {
                    throw Oops.Oh($"{input.SportsEventsCode}-值已存在");
                }

            }
            else
            {
                var id = input.Id;
                var data = await GetSportsType(id);

                //名称和值不能重复
                var isAnyName = await _sportEventsTypeRep.IsAnyAsync(a => a.Id != id && a.IsDelete == false && a.SportsEventsName == input.SportsEventsName);
                if (isAnyName)
                {
                    throw Oops.Oh($"{input.SportsEventsName}-名称已存在");
                }
                var isAnyCode = await _sportEventsTypeRep.IsAnyAsync(a => a.Id != id && a.IsDelete == false && a.SportsEventsCode == input.SportsEventsCode);
                if (isAnyCode)
                {
                    throw Oops.Oh($"{input.SportsEventsCode}-值已存在");
                }

            }
            if (isSame) { throw Oops.Oh($"已存在此场馆编码或者场馆名称"); }

            #endregion

        }
        #endregion
    }
}
